home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 303_01.zip / ROBJ.C < prev    next >
Text File  |  1993-04-01  |  34KB  |  1,490 lines

  1. /*
  2.  *    SCCS:    %W%    %G%    %U%
  3.  *    Read object files.
  4.  *
  5.  *EMACS_MODES:c
  6.  *
  7.  *    This particular module will obviously have to be munged beyond
  8.  *    recognition for another object format.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <a.out.h>
  13. #ifdef    COFF
  14. #include <ldfcn.h>
  15. #include <string.h>
  16. #endif    /*  COFF  */
  17. #include "unc.h"
  18.  
  19. void    gette(), getde(), setde(), putte(), putde();
  20. long    gettw(), getdw();
  21. void    reallst(), lclash(), nomem(), unimpl();
  22. void    addit();
  23. char    *malloc();
  24. long    lseek();
  25.  
  26. int    par_entry, par_round, nmods, donedrel, donebrel;
  27. struct    commit    abstab, comtab, dreltab;
  28. long    trelpos, drelpos, brelpos;
  29.  
  30. #ifdef    COFF
  31. int *symord;    /* convert symbol index to symbol ordinal */
  32.  
  33. #endif    /*  COFF  */
  34. ef_fids    mainfile;
  35.  
  36. symbol    lookup(), inventsymb(), getnsymb();
  37.  
  38. #ifdef    COFF
  39. #define RWORD 1
  40. #define RLONG 2
  41. #endif    /*  COFF  */
  42. #define    DBSIZE    100
  43. #define    STINIT    20
  44.  
  45. /*
  46.  *    Read text segment.  Return 0 if not ok.
  47.  */
  48.  
  49. #ifdef    COFF
  50. int    rtext(ldptr, outf)
  51.   LDFILE *ldptr;        /*  a.out file (possibly in library)  */
  52.   ef_fid    outf;        /*  Output file descriptor  */
  53. #else    /*  !COFF  */
  54. int    rtext(inf, offset, outf)
  55. int    inf;        /*  a.out file (possibly in library)  */
  56. long    offset;        /*  Offset from start of inf of a.out file  */
  57. ef_fid    outf;        /*  Output file descriptor  */
  58. #endif    /*  !COFF  */
  59. {
  60. #ifdef    COFF
  61.    t_entry        tstr;
  62.    struct    aouthdr    unixhdr;
  63.    struct  scnhdr  sect;
  64.    register  long    size;
  65.    register  int    i, l;
  66.    unsigned  short    inbuf[DBSIZE/2];
  67.    
  68.    /*
  69.     *    Initialise fields in structure.
  70.     */
  71.    
  72.    tstr.t_type = T_UNKNOWN;
  73.    tstr.t_vins = 1;        /*  For the moment  */
  74.    tstr.t_bdest = 0;
  75.    tstr.t_gbdest = 0;
  76.    tstr.t_lng = 1;
  77.    tstr.t_reloc = R_NONE;
  78.    tstr.t_rdisp = 0;
  79.    tstr.t_isrel = 0;
  80.    tstr.t_amap = 0;
  81. #else    /*  !COFF  */
  82.     t_entry        tstr;
  83.     struct    bhdr    filhdr;
  84.     register  long    size;
  85.     register  int    i, l;
  86.     unsigned  short    inbuf[DBSIZE/2];
  87.  
  88.     /*
  89.      *    Initialise fields in structure.
  90.      */
  91.     
  92.     tstr.t_type = T_UNKNOWN;
  93.     tstr.t_vins = 1;        /*  For the moment  */
  94.     tstr.t_bdest = 0;
  95.     tstr.t_gbdest = 0;
  96.     tstr.t_lng = 1;
  97.     tstr.t_reloc = R_NONE;
  98.     tstr.t_rdisp = 0;
  99.     tstr.t_isrel = 0;
  100.     tstr.t_amap = 0;
  101. #endif    /*  !COFF  */
  102.     tstr.t_dref = 0;
  103.     tstr.t_relsymb = NULL;
  104.     tstr.t_reldisp = 0;
  105.     tstr.t_lab = NULL;
  106.     tstr.t_lsymb = 0;
  107.     tstr.t_refhi = 0;
  108.     tstr.t_reflo = 0x7fffffff;
  109.     tstr.t_match = 0;
  110.     
  111.     /*
  112.      *    Read a.out header.
  113.      */
  114. #ifndef    COFF
  115.     
  116.     (void) lseek(inf, offset, 0);
  117. #endif    /*  !COFF  */
  118.  
  119. #ifdef    COFF
  120.     if (ldohseek(ldptr) == FAILURE) {    /* no optional header */
  121. #else    /*  !COFF  */
  122.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  123.         return    0;
  124. #endif    /*  !COFF  */
  125.  
  126. #ifdef    COFF
  127.         outf->ef_entry = 0;
  128.         ldshread(ldptr,1,§);        /* text header */
  129.         outf->ef_tbase = sect.s_vaddr;
  130.         outf->ef_tsize = sect.s_size;
  131. #else    /*  !COFF  */
  132.     if  (filhdr.fmagic != FMAGIC  &&  filhdr.fmagic != NMAGIC)
  133.         return    0;
  134. #endif    /*  !COFF  */
  135.  
  136. #ifdef    COFF
  137.         ldshread(ldptr,2,§);        /* data header */
  138.         outf->ef_dbase = sect.s_vaddr;
  139.         outf->ef_dsize = sect.s_size;
  140.  
  141.         ldshread(ldptr,3,§);        /* bss header */
  142.         outf->ef_bbase = sect.s_vaddr;
  143.         outf->ef_bsize = sect.s_size;
  144.         outf->ef_end = sect.s_vaddr + sect.s_size;
  145.     } else {
  146.         FREAD((char *)&unixhdr,sizeof(struct aouthdr),1,ldptr);
  147. #else    /*  !COFF  */
  148.     /*
  149.      *    Warn user if entry point does not tie up.
  150.      */
  151. #endif    /*  !COFF  */
  152.     
  153. #ifdef    COFF
  154.         if ( N_BADMAG(unixhdr) )
  155.         return    0;
  156. #else    /*  !COFF  */
  157.     if  (filhdr.entry != par_entry)
  158.         (void) fprintf(stderr, "Warning: File has -R%X\n", filhdr.entry);
  159. #endif    /*  !COFF  */
  160.  
  161. #ifdef    COFF
  162.         outf->ef_entry = unixhdr.entry;
  163.         outf->ef_tbase = unixhdr.text_start;
  164.         outf->ef_dbase = unixhdr.data_start;
  165.         outf->ef_bbase = outf->ef_dbase + unixhdr.dsize;
  166.         outf->ef_end = outf->ef_bbase + unixhdr.bsize;
  167. #else    /*  !COFF  */
  168.     outf->ef_entry = filhdr.entry;
  169.     outf->ef_tbase = filhdr.entry;
  170.     outf->ef_dbase = filhdr.tsize + filhdr.entry;
  171. #endif    /*  !COFF  */
  172.  
  173. #ifdef    COFF
  174.         outf->ef_tsize = unixhdr.tsize;
  175.         outf->ef_dsize = unixhdr.dsize;
  176.         outf->ef_bsize = unixhdr.bsize;
  177.     }
  178. #else    /*  !COFF  */
  179.     if  (filhdr.fmagic == NMAGIC)
  180.         outf->ef_dbase = (outf->ef_dbase + par_round) & (~par_round);
  181.  
  182.     outf->ef_bbase = outf->ef_dbase + filhdr.dsize;
  183.     outf->ef_end = outf->ef_bbase + filhdr.bsize;
  184.  
  185.     outf->ef_tsize = filhdr.tsize;
  186.     outf->ef_dsize = filhdr.dsize;
  187.     outf->ef_bsize = filhdr.bsize;
  188. #endif    /*  !COFF  */
  189.     
  190. #ifdef    COFF
  191.     ldsseek(ldptr,1);    /* seek to text section */
  192. #else    /*  !COFF  */
  193.     tstr.t_data = outf->ef_dbase;
  194.  
  195.     (void) lseek(inf, offset + TEXTPOS, 0);
  196. #endif    /*  !COFF  */
  197.     
  198.     size = outf->ef_tsize;
  199.     
  200.     while  (size > 1)  {
  201.         l = size > DBSIZE? DBSIZE: size;
  202. #ifdef    COFF
  203.         if  (FREAD((char *)inbuf,1,l,ldptr) != l)
  204. #else    /*  !COFF  */
  205.         if  (read(inf, (char *)inbuf, l) != l)
  206. #endif    /*  !COFF  */
  207.             return    0;
  208.         l /= 2;
  209.         for  (i = 0;  i < l;  i++)  {
  210.             tstr.t_contents = inbuf[i];
  211.             (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
  212.         }
  213.         size -= l + l;
  214.     }
  215.     
  216.     /*
  217.      *    Extra one to cope with "etext".
  218.      */
  219.     
  220.     (void) write(outf->ef_t, (char *)&tstr, sizeof(tstr));
  221.     return    1;
  222. }
  223. #ifndef    COFF
  224.  
  225. #endif    /*  !COFF  */
  226. /*
  227.  *    Same sort of thing for the data segment.
  228.  */
  229.  
  230. #ifdef    COFF
  231. int    rdata(ldptr, outf)
  232. LDFILE *ldptr;        /*  a.out file (possibly in library)  */
  233. #else    /*  !COFF  */
  234. int    rdata(inf, offset, outf)
  235. int    inf;        /*  a.out file (possibly in library)  */
  236. long    offset;        /*  Offset from start of inf of a.out file  */
  237. #endif    /*  !COFF  */
  238. ef_fid    outf;        /*  Output file descriptor  */
  239. {
  240.     d_entry        dstr;
  241. #ifndef    COFF
  242.     struct    bhdr    filhdr;
  243. #endif    /*  !COFF  */
  244.     register  long    size;
  245.     register  int    i, l;
  246.     unsigned  char    inbuf[DBSIZE];
  247.  
  248.     /*
  249.      *    Initialise fields in structure.
  250.      */
  251.     
  252.     dstr.d_type = D_BYTE;
  253.     dstr.d_reloc = R_NONE;
  254.     dstr.d_lng = 1;
  255.     dstr.d_relsymb = NULL;
  256.     dstr.d_reldisp = 0;
  257.     dstr.d_lab = NULL;
  258.     
  259. #ifdef    COFF
  260.     ldsseek(ldptr,2);    /* seek to data section */
  261. #else    /*  !COFF  */
  262.     /*
  263.      *    Read a.out header.
  264.      */
  265. #endif    /*  !COFF  */
  266.     
  267. #ifndef    COFF
  268.     (void) lseek(inf, offset, 0);
  269.  
  270.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  271.         return    0;
  272.  
  273.     (void) lseek(inf, offset + DATAPOS, 0);
  274.     
  275. #endif    /*  !COFF  */
  276.     size = outf->ef_dsize;
  277.     
  278.     while  (size > 0)  {
  279.         l = size > DBSIZE? DBSIZE: size;
  280. #ifdef    COFF
  281.         if  (FREAD((char *)inbuf,1,l,ldptr) != l)
  282. #else    /*  !COFF  */
  283.         if  (read(inf, (char *)inbuf, l) != l)
  284. #endif    /*  !COFF  */
  285.             return    0;
  286.         for  (i = 0;  i < l;  i++)  {
  287.             dstr.d_contents = inbuf[i];
  288.             (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  289.         }
  290.         size -= l;
  291.     }
  292.     
  293.     /*
  294.      *    Repeat for BSS segment.
  295.      */
  296.  
  297.     dstr.d_contents = 0;
  298.     for  (size = outf->ef_bsize;  size > 0;  size--)
  299.         (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  300.     
  301.     /*
  302.      *    Extra one to cope with "end".
  303.      */
  304.     
  305.     (void) write(outf->ef_d, (char *)&dstr, sizeof(dstr));
  306.     return    1;
  307. }
  308.  
  309. /*
  310.  *    Process symbol table segment.
  311.  */
  312.  
  313. #ifdef    COFF
  314. int    rsymb(ldptr, dproc, outf)
  315. LDFILE *ldptr;        /*  a.out file (possibly in library)  */
  316. #else    /*  !COFF  */
  317. int    rsymb(inf, offset, dproc, outf)
  318. int    inf;        /*  a.out file (possibly in library)  */
  319. long    offset;        /*  Offset from start of inf of a.out file  */
  320. #endif    /*  !COFF  */
  321. symbol    (*dproc)();
  322. register  ef_fid  outf;    /*  Output file descriptor  */
  323. {
  324. #ifdef    COFF
  325. #define SYMLENGTH 256
  326. #endif    /*  COFF  */
  327.     register  symbol  csym;
  328. #ifdef    COFF
  329.      struct    syment    isym;
  330.     register  int   nsyms,symindex;
  331.     unsigned long   stroff;
  332.      char    inbuf[SYMLENGTH+1], *cp;
  333.     int ord;
  334. #else    /*  !COFF  */
  335.     struct    bhdr    filhdr;
  336.     struct    sym    isym;
  337.     register  long    size;
  338.     register  int    i, l;
  339.     char    inbuf[SYMLENGTH+1];
  340. #endif    /*  !COFF  */
  341.  
  342. #ifdef    COFF
  343.     nsyms = HEADER(ldptr).f_nsyms;
  344.     stroff = HEADER(ldptr).f_symptr + nsyms*sizeof(struct syment);
  345. #else    /*  !COFF  */
  346.     /*
  347.      *    Read a.out header.
  348.      */
  349.     
  350.     (void) lseek(inf, offset, 0);
  351. #endif    /*  !COFF  */
  352.  
  353. #ifdef    COFF
  354.     if  (nsyms <= 0)
  355.         nsyms = STINIT;
  356. #else    /*  !COFF  */
  357.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  358.         return    0;
  359. #endif    /*  !COFF  */
  360.  
  361. #ifdef    COFF
  362.     outf->ef_stvec = (symbol *) malloc(nsyms * sizeof(symbol));
  363.     symord = (int *) malloc(nsyms * sizeof(int));
  364. #else    /*  !COFF  */
  365.     offset += SYMPOS;
  366.     size = filhdr.ssize;
  367.     if  (size <= 0)
  368.         return    1;
  369.  
  370.     /*
  371.      *    Guesstimate symbol table vector size.
  372.      */
  373.  
  374.     l = size / (sizeof(struct sym) + 4);
  375.     if  (l <= 0)
  376.         l = STINIT;
  377.  
  378.     outf->ef_stvec = (symbol *) malloc(l * sizeof(symbol));
  379. #endif    /*  !COFF  */
  380.     if  (outf->ef_stvec == NULL)
  381.         nomem();
  382.  
  383.     outf->ef_stcnt = 0;
  384. #ifdef    COFF
  385.     outf->ef_stmax = nsyms;
  386.     ord = 0;
  387. #else    /*  !COFF  */
  388.     outf->ef_stmax = l;
  389. #endif    /*  !COFF  */
  390.     
  391. #ifdef    COFF
  392.      for  (symindex=0; symindex<nsyms; symindex++)  {
  393.         ldtbread(ldptr,symindex,&isym);
  394.         if (isym.n_zeroes == 0) {    /* get from string table */
  395.             FSEEK(ldptr,stroff + isym.n_offset,0);
  396.             cp = inbuf;
  397.             do {
  398.              if (FREAD(cp,1,1,ldptr) != 1)/* Read symbol chars 1-by-1 */
  399.                  return 0;
  400.              if ( cp - inbuf >= SYMLENGTH )/* Check against buffer overflow */
  401.                  return 0;
  402.             } while (*cp++ != '\0');/* Terminate on null byte */
  403.         } else {            /* get from symbol field */
  404.             strncpy(inbuf,isym.n_name,8);
  405.             inbuf[8] = '\0';
  406.         }
  407.          csym = (*dproc)(lookup(inbuf), convtosun(&isym),
  408.                 isym.n_value, outf);
  409.          if (outf->ef_stcnt >= outf->ef_stmax)
  410. #else    /*  !COFF  */
  411.     while  (size > sizeof(struct sym))  {
  412.         (void) lseek(inf, offset, 0);
  413.         if  (read(inf, (char *)&isym, sizeof(isym)) != sizeof(isym))
  414.             return    0;
  415.         size -= sizeof(isym);
  416.         l = SYMLENGTH;
  417.         if  (l > size)
  418.             l = size;
  419.         if  (read(inf, inbuf, l) != l)
  420.             return    0;
  421.         inbuf[l] = '\0';
  422.         for  (i = 0; inbuf[i] != '\0';  i++)
  423.             ;
  424.         size -= i + 1;
  425.         offset += sizeof(isym) + i + 1;
  426.         csym = (*dproc)(lookup(inbuf), isym.stype, isym.svalue, outf);
  427.         if  (outf->ef_stcnt >= outf->ef_stmax)
  428. #endif    /*  !COFF  */
  429.             reallst(outf);
  430.         outf->ef_stvec[outf->ef_stcnt++] = csym;
  431. #ifdef    COFF
  432.         symord[symindex] = ord++;        /* record ordinal */
  433.         symindex += isym.n_numaux;        /* skip aux entries */
  434. #endif    /*  COFF  */
  435.     }
  436.     return    1;
  437. }
  438.  
  439. /*
  440.  *    Process relocation stuff.  -1 error, 0 no relocation, 1 relocation.
  441.  */
  442.  
  443. #ifdef    COFF
  444. int    rrel(ldptr, ldptr2, outf)
  445. LDFILE *ldptr,*ldptr2;    /*  a.out file (possibly in library)  */
  446. #else    /*  !COFF  */
  447. int    rrel(inf, offset, outf)
  448. int    inf;        /*  a.out file (possibly in library)  */
  449. long    offset;        /*  Offset from start of inf of a.out file  */
  450. #endif    /*  !COFF  */
  451. ef_fid    outf;        /*  Output file descriptor  */
  452. {
  453. #ifdef    COFF
  454.      struct    reloc    crel;
  455.     struct scnhdr tsect,dsect;
  456.     struct syment isym;
  457. #else    /*  !COFF  */
  458.     struct    bhdr    filhdr;
  459.     struct    reloc    crel;
  460. #endif    /*  !COFF  */
  461.     t_entry    tstr;
  462.     d_entry    dstr;
  463. #ifdef    COFF
  464.     register  int    nreloc;
  465. #else    /*  !COFF  */
  466.     register  long    size;
  467. #endif    /*  !COFF  */
  468.     long    cont, pos;
  469.  
  470. #ifdef    COFF
  471.     ldshread(ldptr,1,&tsect);
  472.     ldshread(ldptr,2,&dsect);
  473.      if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
  474. #else    /*  !COFF  */
  475.     /*
  476.      *    Read a.out header.
  477.      */
  478.     
  479.     (void) lseek(inf, offset, 0);
  480.  
  481.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  482.         return    -1;
  483.     if  (filhdr.rtsize <= 0  &&  filhdr.rdsize <= 0)
  484. #endif    /*  !COFF  */
  485.         return    0;
  486.  
  487. #ifdef    COFF
  488.     nreloc = tsect.s_nreloc;
  489. #else    /*  !COFF  */
  490.     size  =  filhdr.rtsize;
  491. #endif    /*  !COFF  */
  492.  
  493. #ifdef    COFF
  494.     ldrseek(ldptr,1);
  495.      while  (nreloc-- > 0)  {
  496.         if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  497. #else    /*  !COFF  */
  498.     (void) lseek(inf, RTEXTPOS + offset, 0);
  499.     while  (size >= sizeof(struct reloc))  {
  500.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  501. #endif    /*  !COFF  */
  502.             return    -1;
  503.  
  504. #ifdef    COFF
  505.          pos = crel.r_vaddr;
  506. #else    /*  !COFF  */
  507.         pos = crel.rpos + outf->ef_tbase;
  508. #endif    /*  !COFF  */
  509.         gette(outf, pos, &tstr);
  510. #ifdef    COFF
  511.         if (crel.r_type == R_ABS)
  512.             tstr.t_reloc = R_NONE;
  513.         else
  514.             tstr.t_reloc = R_LONG;    /* what about PC-relative? */
  515.         ldtbread(ldptr2,crel.r_symndx,&isym);
  516.         if (isym.n_sclass == C_EXT) {
  517.              tstr.t_relsymb = outf->ef_stvec[symord[crel.r_symndx]];
  518.              tstr.t_reldisp = gettw(outf, pos, (int)tstr.t_reloc);
  519. #else    /*  !COFF  */
  520.         tstr.t_reloc = crel.rsize + 1;    /*  Fiddle!  YUK!!!  */
  521.         tstr.t_rdisp = crel.rdisp;
  522.         tstr.t_rptr = crel.rsegment;
  523.         if  (crel.rsegment == REXT)  {
  524.             if  (crel.rsymbol >= outf->ef_stcnt)
  525.                 return  -1;
  526.             tstr.t_relsymb = outf->ef_stvec[crel.rsymbol];
  527.             tstr.t_reldisp = gettw(outf, pos, (int)crel.rsize+1);
  528. #endif    /*  !COFF  */
  529.         }
  530.         else  {
  531. #ifdef    COFF
  532.              cont = gettw(outf, pos, (int)tstr.t_reloc);
  533.              tstr.t_relsymb = getnsymb(outf, convtosun(&isym), cont);
  534. #else    /*  !COFF  */
  535.             cont = gettw(outf, pos, (int)crel.rsize+1);
  536.             tstr.t_relsymb = getnsymb(outf, crel.rsegment, cont);
  537. #endif    /*  !COFF  */
  538.         }
  539.         tstr.t_relsymb->s_used++;
  540.         putte(outf, pos, &tstr);
  541. #ifndef    COFF
  542.         size -= sizeof(crel);
  543. #endif    /*  !COFF  */
  544.     }
  545.     
  546.     /*
  547.      *    And now repeat all that for data relocations.
  548.      */
  549.     
  550. #ifdef    COFF
  551.     nreloc = dsect.s_nreloc;
  552. #else    /*  !COFF  */
  553.     size  =  filhdr.rdsize;
  554. #endif    /*  !COFF  */
  555.     
  556. #ifdef    COFF
  557.     ldrseek(ldptr,2);
  558.      while  (nreloc-- > 0)  {
  559.         if (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  560. #else    /*  !COFF  */
  561.     (void) lseek(inf, RDATAPOS + offset, 0);
  562.     while  (size >= sizeof(struct reloc))  {
  563.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  564. #endif    /*  !COFF  */
  565.             return    -1;
  566.  
  567. #ifdef    COFF
  568.          pos = crel.r_vaddr;
  569. #else    /*  !COFF  */
  570.         pos = crel.rpos + outf->ef_dbase;
  571. #endif    /*  !COFF  */
  572.         getde(outf, pos, &dstr);
  573. #ifdef    COFF
  574.         if (crel.r_type == R_ABS)
  575.             dstr.d_reloc = R_NONE;
  576.         else
  577.             dstr.d_reloc = R_LONG;    /* what about PC-relative? */
  578. #else    /*  !COFF  */
  579.         dstr.d_reloc = crel.rsize + 1;    /*  Fiddle!  YUK!!!  */
  580.         dstr.d_rptr = crel.rsegment;
  581. #endif    /*  !COFF  */
  582.  
  583. #ifdef    COFF
  584.         ldtbread(ldptr2,crel.r_symndx,&isym);
  585.         if (isym.n_sclass == C_EXT) {
  586.              dstr.d_relsymb = outf->ef_stvec[symord[crel.r_symndx]];
  587.              dstr.d_reldisp = getdw(outf, pos, (int)dstr.d_reloc);
  588. #else    /*  !COFF  */
  589.         if  (crel.rsegment == REXT)  {
  590.             if  (crel.rsymbol >= outf->ef_stcnt)
  591.                 return  -1;
  592.             dstr.d_relsymb = outf->ef_stvec[crel.rsymbol];
  593.             dstr.d_reldisp = getdw(outf, pos, (int)crel.rsize+1);
  594. #endif    /*  !COFF  */
  595.         }
  596.         else  {
  597. #ifdef    COFF
  598.              cont = getdw(outf, pos, (int)dstr.d_reloc);
  599.              dstr.d_relsymb = getnsymb(outf, convtosun(&isym), cont);
  600.              if  (dstr.d_relsymb->s_type == S_TEXT)  {
  601. #else    /*  !COFF  */
  602.             cont = getdw(outf, pos, (int)crel.rsize+1);
  603.             dstr.d_relsymb = getnsymb(outf, crel.rsegment, cont);
  604.             if  (dstr.d_relsymb->s_type == TEXT)  {
  605. #endif    /*  !COFF  */
  606.                 gette(outf, cont, &tstr);
  607.                 tstr.t_dref = 1;
  608.                 putte(outf, cont, &tstr);
  609.             }
  610.         }
  611. #ifdef    COFF
  612.          switch  (dstr.d_reloc)  {
  613. #else    /*  !COFF  */
  614.         switch  (crel.rsize)  {
  615. #endif    /*  !COFF  */
  616.         default:
  617.             unimpl("Data byte relocation");
  618.             break;
  619. #ifdef    COFF
  620.         case  R_WORD:
  621. #else    /*  !COFF  */
  622.         case  RWORD:
  623. #endif    /*  !COFF  */
  624.             unimpl("data word reloc");
  625.             dstr.d_type = D_WORD;
  626.             dstr.d_lng = 2;
  627.             setde(outf, pos+1, D_CONT, 1);
  628.             break;
  629. #ifdef    COFF
  630.         case  R_LONG:
  631. #else    /*  !COFF  */
  632.         case  RLONG:
  633. #endif    /*  !COFF  */
  634.             dstr.d_type = D_ADDR;
  635.             dstr.d_lng = 4;
  636.             setde(outf, pos+1, D_CONT, 1);
  637.             setde(outf, pos+2, D_CONT, 1);
  638.             setde(outf, pos+3, D_CONT, 1);
  639.             break;
  640.         }
  641.         dstr.d_relsymb->s_used++;
  642.         putde(outf, pos, &dstr);
  643. #ifndef    COFF
  644.         size -= sizeof(crel);
  645. #endif    /*  !COFF  */
  646.     }
  647.     return 1;
  648. }
  649.  
  650. /*
  651.  *    Process a symbol.
  652.  */
  653.  
  654. symbol    dosymb(sy, type, val, fid)
  655. register  symbol  sy;
  656. int    type;
  657. long    val;
  658. ef_fid    fid;
  659. {
  660.     t_entry    tstr;
  661.     d_entry    dstr;
  662.     
  663.     if  (!sy->s_newsym)  {
  664. #ifdef    COFF
  665.          if  (type & S_EXT)  {
  666. #else    /*  !COFF  */
  667.         if  (type & EXTERN)  {
  668. #endif    /*  !COFF  */
  669.             (void) fprintf(stderr, "Duplicate symbol %s\n", sy->s_name);
  670. #ifdef    COFF
  671.             /* exit(10);  temporary? */
  672. #else    /*  !COFF  */
  673.             exit(10);
  674. #endif    /*  !COFF  */
  675.         }
  676.         if  (++sy->s_defs > nmods)
  677.             nmods = sy->s_defs;
  678.         sy = inventsymb("DUP");
  679.     }
  680.  
  681.     sy->s_value = val;
  682.     
  683.     switch  (type)  {
  684.     default:
  685.         return    NULL;
  686.         
  687. #ifdef    COFF
  688.      case  S_EXT|S_UNDF:
  689. #else    /*  !COFF  */
  690.     case  EXTERN|UNDEF:
  691. #endif    /*  !COFF  */
  692.         if  (val != 0)  {
  693. #ifdef    COFF
  694.              sy->s_type = S_COMM;
  695. #else    /*  !COFF  */
  696.             sy->s_type = COMM;
  697. #endif    /*  !COFF  */
  698.             addit(&comtab, sy);
  699.         }
  700.         else
  701. #ifdef    COFF
  702.             sy->s_type = S_UNDF;
  703. #else    /*  !COFF  */
  704.             sy->s_type = N_UNDF;
  705. #endif    /*  !COFF  */
  706.         sy->s_glob = 1;
  707.         break;
  708.         
  709. #ifdef    COFF
  710.      case  S_EXT|S_ABS:
  711.         sy->s_type = S_ABS;
  712. #else    /*  !COFF  */
  713.     case  EXTERN|ABS:
  714.         sy->s_type = N_ABS;
  715. #endif    /*  !COFF  */
  716.         sy->s_glob = 1;
  717.         addit(&abstab, sy);
  718.         break;
  719.         
  720. #ifdef    COFF
  721.      case  S_ABS:
  722.         sy->s_type = S_ABS;
  723. #else    /*  !COFF  */
  724.     case  ABS:
  725.         sy->s_type = N_ABS;
  726. #endif    /*  !COFF  */
  727.         addit(&abstab, sy);
  728.         break;
  729.         
  730. #ifdef    COFF
  731.      case  S_EXT|S_TEXT:
  732.      case  S_TEXT:
  733.         sy->s_type = S_TEXT;
  734. #else    /*  !COFF  */
  735.     case  EXTERN|TEXT:
  736.     case  TEXT:
  737.         sy->s_type = N_TEXT;
  738. #endif    /*  !COFF  */
  739.         gette(fid, val, &tstr);
  740.         tstr.t_bdest = 1;
  741. #ifdef    COFF
  742.          if  (type & S_EXT)  {
  743. #else    /*  !COFF  */
  744.         if  (type & EXTERN)  {
  745. #endif    /*  !COFF  */
  746.             tstr.t_gbdest = 1;
  747.             sy->s_glob = 1;
  748.         }
  749.         sy->s_link = tstr.t_lab;
  750.         tstr.t_lab = sy;
  751.         putte(fid, val, &tstr);
  752.         break;
  753.         
  754. #ifdef    COFF
  755.      case  S_BSS:
  756.      case  S_EXT|S_BSS:
  757.         sy->s_type = S_BSS;
  758. #else    /*  !COFF  */
  759.     case  BSS:
  760.     case  EXTERN|BSS:
  761.         sy->s_type = N_BSS;
  762. #endif    /*  !COFF  */
  763.         goto    datrest;
  764. #ifdef    COFF
  765.      case  S_DATA:
  766.      case  S_EXT|S_DATA:
  767.         sy->s_type = S_DATA;
  768. #else    /*  !COFF  */
  769.     case  DATA:
  770.     case  EXTERN|DATA:
  771.         sy->s_type = N_DATA;
  772. #endif    /*  !COFF  */
  773.     datrest:
  774.         getde(fid, val, &dstr);
  775. #ifdef    COFF
  776.          if  (type & S_EXT)
  777. #else    /*  !COFF  */
  778.         if  (type & EXTERN)
  779. #endif    /*  !COFF  */
  780.             sy->s_glob = 1;
  781.         sy->s_link = dstr.d_lab;
  782.         dstr.d_lab = sy;
  783.         putde(fid, val, &dstr);
  784.         break;
  785.     }
  786.     
  787.     sy->s_newsym = 0;
  788.     return    sy;
  789. }
  790.  
  791. #ifdef    COFF
  792.  
  793. #endif    /*  COFF  */
  794. /*
  795.  *    Process relocation stuff in putative library modules.
  796.  *    The main function of all this is to mark which bits of the text
  797.  *    not to look at as I compare the stuff.
  798.  *
  799.  *    As with "rrel", return -1 error, 0 no relocation, 1 relocation.
  800.  */
  801.  
  802. #ifdef    COFF
  803. int    rrell1(ldptr, outf)
  804. LDFILE *ldptr;        /*  a.out file (possibly in library)  */
  805. #else    /*  !COFF  */
  806. int    rrell1(inf, offset, outf)
  807. int    inf;        /*  a.out file (possibly in library)  */
  808. long    offset;        /*  Offset from start of inf of a.out file  */
  809. #endif    /*  !COFF  */
  810. ef_fid    outf;        /*  Output file descriptor  */
  811. {
  812. #ifdef    COFF
  813.      struct    reloc    crel;
  814.     struct scnhdr tsect,dsect;
  815. #else    /*  !COFF  */
  816.     struct    bhdr    filhdr;
  817.     struct    reloc    crel;
  818. #endif    /*  !COFF  */
  819.     t_entry    tstr;
  820. #ifdef    COFF
  821.     register  int    nreloc;
  822. #else    /*  !COFF  */
  823.     register  long    size;
  824. #endif    /*  !COFF  */
  825.     long    pos;
  826.  
  827. #ifdef    COFF
  828.     ldshread(ldptr,1,&tsect);
  829.     ldshread(ldptr,2,&dsect);
  830.      if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
  831. #else    /*  !COFF  */
  832.     /*
  833.      *    Read a.out header.
  834.      */
  835.     
  836.     (void) lseek(inf, offset, 0);
  837.  
  838.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  839.         return    -1;
  840.     if  (filhdr.rtsize <= 0  &&  filhdr.rdsize <= 0)
  841. #endif    /*  !COFF  */
  842.         return    0;
  843.  
  844. #ifdef    COFF
  845.     nreloc = tsect.s_nreloc;
  846. #else    /*  !COFF  */
  847.     size  =  filhdr.rtsize;
  848. #endif    /*  !COFF  */
  849.  
  850. #ifdef    COFF
  851.     ldrseek(ldptr,1);
  852.      while  (nreloc-- > 0)  {
  853.         if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  854. #else    /*  !COFF  */
  855.     (void) lseek(inf, RTEXTPOS + offset, 0);
  856.     while  (size >= sizeof(struct reloc))  {
  857.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  858. #endif    /*  !COFF  */
  859.             return    -1;
  860.  
  861. #ifdef    COFF
  862.          pos = crel.r_vaddr;
  863. #else    /*  !COFF  */
  864.         pos = crel.rpos + outf->ef_tbase;
  865. #endif    /*  !COFF  */
  866.         gette(outf, pos, &tstr);
  867. #ifdef    COFF
  868.         if (crel.r_type == R_ABS)
  869.             tstr.t_reloc = R_NONE;
  870.         else
  871.             tstr.t_reloc = R_LONG;    /* what about PC-relative? */
  872. #else    /*  !COFF  */
  873.         tstr.t_reloc = crel.rsize + 1;    /*  Fiddle!  YUK!!!  */
  874.         tstr.t_rdisp = crel.rdisp;
  875.         tstr.t_rptr = crel.rsegment;
  876. #endif    /*  !COFF  */
  877.         tstr.t_isrel = 1;
  878.         putte(outf, pos, &tstr);
  879. #ifdef    COFF
  880.          if  (tstr.t_reloc == R_LONG)  {
  881. #else    /*  !COFF  */
  882.         if  (crel.rsize == RLONG)  {
  883. #endif    /*  !COFF  */
  884.             gette(outf, pos+2, &tstr);
  885.             tstr.t_isrel = 1;
  886.             putte(outf, pos+2, &tstr);
  887.         }
  888. #ifndef    COFF
  889.         size -= sizeof(crel);
  890. #endif    /*  !COFF  */
  891.     }
  892.     
  893.     /*
  894.      *    Dont bother with data relocation at this stage. We'll
  895.      *    tie that up later.
  896.      */
  897.     
  898.     return 1;
  899. }
  900.  
  901. /*
  902.  *    Process a symbol in library file.  The extern variable trelpos gives
  903.  *    the place in the main file where the library module is relocated.
  904.  *    We don't know the data position until we do the final merge, perhaps
  905.  *    not even then.
  906.  */
  907. #ifdef    COFF
  908. /* trelpos ??? */
  909. #endif    /*  COFF  */
  910.  
  911. symbol    dolsymb(sy, type, val, fid)
  912. register  symbol  sy;
  913. int    type;
  914. long    val;
  915. ef_fid    fid;
  916. {
  917.     t_entry    tstr;
  918.     
  919.     switch  (type)  {
  920.     default:
  921.         return    NULL;
  922.         
  923. #ifdef    COFF
  924.      case  S_EXT|S_UNDF:
  925. #else    /*  !COFF  */
  926.     case  EXTERN|UNDEF:
  927. #endif    /*  !COFF  */
  928.         if  (!sy->s_newsym)
  929.             return    sy;
  930.         sy->s_value = val;
  931.         if  (val != 0)  {
  932. #ifdef    COFF
  933.              sy->s_type = S_COMM;
  934. #else    /*  !COFF  */
  935.             sy->s_type = COMM;
  936. #endif    /*  !COFF  */
  937.             addit(&dreltab, sy);
  938.         }
  939.         else
  940. #ifdef    COFF
  941.             sy->s_type = S_UNDF;
  942. #else    /*  !COFF  */
  943.             sy->s_type = N_UNDF;
  944. #endif    /*  !COFF  */
  945.         sy->s_glob = 1;
  946.         break;
  947.         
  948. #ifdef    COFF
  949.      case  S_EXT|S_ABS:
  950. #else    /*  !COFF  */
  951.     case  EXTERN|ABS:
  952. #endif    /*  !COFF  */
  953.         if  (!sy->s_newsym)  {
  954. #ifdef    COFF
  955.             if  (sy->s_type != S_ABS || sy->s_value != val)
  956. #else    /*  !COFF  */
  957.             if  (sy->s_type != N_ABS || sy->s_value != val)
  958. #endif    /*  !COFF  */
  959.                 lclash("abs");
  960.         }
  961. #ifdef    COFF
  962.         sy->s_type = S_ABS;
  963. #else    /*  !COFF  */
  964.         sy->s_type = N_ABS;
  965. #endif    /*  !COFF  */
  966.         sy->s_value = val;
  967.         sy->s_glob = 1;
  968.         addit(&abstab, sy);
  969.         break;
  970.         
  971. #ifdef    COFF
  972.      case  S_EXT|S_TEXT:
  973.         sy->s_type = S_TEXT;
  974. #else    /*  !COFF  */
  975.     case  EXTERN|TEXT:
  976.         sy->s_type = N_TEXT;
  977. #endif    /*  !COFF  */
  978.         val += trelpos - fid->ef_tbase;
  979.         if  (!sy->s_newsym)  {
  980.             if  (val != sy->s_value)
  981.                 lclash("tsym");
  982.             return    sy;
  983.         }
  984.         sy->s_value = val;
  985.         gette(&mainfile, val, &tstr);
  986.         tstr.t_bdest = 1;
  987.         tstr.t_gbdest = 1;
  988.         sy->s_glob = 1;
  989.         sy->s_link = tstr.t_lab;
  990.         tstr.t_lab = sy;
  991.         putte(&mainfile, val, &tstr);
  992.         break;
  993.  
  994. #ifdef    COFF
  995.      case  S_EXT|S_BSS:
  996. #else    /*  !COFF  */
  997.     case  EXTERN|BSS:
  998. #endif    /*  !COFF  */
  999.         if  (!sy->s_newsym)
  1000.             return    sy;
  1001. #ifdef    COFF
  1002.         sy->s_type = S_BSS;
  1003. #else    /*  !COFF  */
  1004.         sy->s_type = N_BSS;
  1005. #endif    /*  !COFF  */
  1006.         sy->s_value = val - fid->ef_bbase;
  1007.         goto    datrest;
  1008.  
  1009. #ifdef    COFF
  1010.      case  S_EXT|S_DATA:
  1011. #else    /*  !COFF  */
  1012.     case  EXTERN|DATA:
  1013. #endif    /*  !COFF  */
  1014.         if  (!sy->s_newsym)
  1015.             return    sy;
  1016. #ifdef    COFF
  1017.         sy->s_type = S_DATA;
  1018. #else    /*  !COFF  */
  1019.         sy->s_type = N_DATA;
  1020. #endif    /*  !COFF  */
  1021.         sy->s_value = val - fid->ef_dbase;
  1022.     datrest:
  1023.         sy->s_glob = 1;
  1024.         addit(&dreltab, sy);
  1025.         break;
  1026.     }
  1027.     
  1028.     sy->s_newsym = 0;
  1029.     return    sy;
  1030. }
  1031.  
  1032. /*
  1033.  *    Change definition of undefined symbol as we define it.
  1034.  */
  1035.  
  1036. void    reassign(sy, val)
  1037. register  symbol  sy;
  1038. long    val;
  1039. {
  1040.     sy->s_value = val;
  1041.  
  1042.     if  (val < mainfile.ef_tbase)  {
  1043. #ifdef    COFF
  1044.         sy->s_type = S_ABS;
  1045. #else    /*  !COFF  */
  1046.         sy->s_type = N_ABS;
  1047. #endif    /*  !COFF  */
  1048.         addit(&abstab, sy);
  1049.     }
  1050.     else  if  (val < mainfile.ef_dbase)  {
  1051.         t_entry    tstr;
  1052.         
  1053. #ifdef    COFF
  1054.         sy->s_type = S_TEXT;
  1055. #else    /*  !COFF  */
  1056.         sy->s_type = N_TEXT;
  1057. #endif    /*  !COFF  */
  1058.         gette(&mainfile, val, &tstr);
  1059.         tstr.t_bdest = 1;
  1060.         tstr.t_gbdest = 1;
  1061.         sy->s_glob = 1;
  1062.         sy->s_link = tstr.t_lab;
  1063.         tstr.t_lab = sy;
  1064.         putte(&mainfile, val, &tstr);
  1065.     }
  1066.     else  {
  1067.         d_entry dstr;
  1068.         
  1069. #ifdef    COFF
  1070.         sy->s_type = val < mainfile.ef_bbase? S_DATA: S_BSS;
  1071. #else    /*  !COFF  */
  1072.         sy->s_type = val < mainfile.ef_bbase? N_DATA: N_BSS;
  1073. #endif    /*  !COFF  */
  1074.         getde(&mainfile, val, &dstr);
  1075.         sy->s_link = dstr.d_lab;
  1076.         dstr.d_lab = sy;
  1077.         putde(&mainfile, val, &dstr);
  1078.     }
  1079. }
  1080.  
  1081. /*
  1082.  *    When we discover where bss or data come, reallocate the table.
  1083.  */
  1084.  
  1085. void    zapdat(seg, inc)
  1086. int    seg;
  1087. long    inc;
  1088. {
  1089.     register  int    i;
  1090.     register  symbol  csymb;
  1091.     d_entry    dent;
  1092.     
  1093.     for  (i = 0;  i < dreltab.c_int;  i++) {
  1094.         csymb = dreltab.c_symb[i];
  1095.         if  (csymb->s_type != seg)
  1096.             continue;
  1097.         csymb->s_value += inc;
  1098.         getde(&mainfile, csymb->s_value, &dent);
  1099.         csymb->s_link = dent.d_lab;
  1100.         dent.d_lab = csymb;
  1101.         putde(&mainfile, csymb->s_value, &dent);
  1102.     }
  1103. }
  1104.  
  1105. /*
  1106.  *    Process relocation stuff in library module which we are inserting.
  1107.  *    Horrors if something goes wrong.
  1108.  */
  1109. #ifdef    COFF
  1110. /* trelpos, drelpos ??? */
  1111. #endif    /*  COFF  */
  1112.  
  1113. #ifdef    COFF
  1114. rrell2(ldptr, ldptr2, outf)
  1115. LDFILE *ldptr,*ldptr2;    /*  a.out file (possibly in library)  */
  1116. #else    /*  !COFF  */
  1117. void    rrell2(inf, offset, outf)
  1118. int    inf;        /*  a.out file (possibly in library)  */
  1119. long    offset;        /*  Offset from start of inf of a.out file  */
  1120. #endif    /*  !COFF  */
  1121. ef_fid    outf;        /*  Output file descriptor  */
  1122. {
  1123. #ifdef    COFF
  1124.      struct    reloc    crel;
  1125. #else    /*  !COFF  */
  1126.     struct    bhdr    filhdr;
  1127.     struct    reloc    crel;
  1128. #endif    /*  !COFF  */
  1129.     t_entry    mtstr;
  1130.     d_entry    mdstr;
  1131. #ifdef    COFF
  1132.     struct scnhdr tsect,dsect;
  1133.     struct syment isym;
  1134.     int nreloc;
  1135.     unsigned rtype;
  1136. #endif    /*  COFF  */
  1137.     register  long    size;
  1138.     register  symbol  csymb;
  1139.     long    pos, mpos, mval, lval;
  1140.     int    dhere = 0;        /*  Mark whether bss done  */
  1141.  
  1142. #ifdef    COFF
  1143.     ldshread(ldptr,1,&tsect);
  1144.     ldshread(ldptr,2,&dsect);
  1145.      if  (tsect.s_nreloc <= 0  &&  dsect.s_nreloc <= 0)
  1146.         return    0;
  1147. #else    /*  !COFF  */
  1148.     /*
  1149.      *    Read a.out header.
  1150.      */
  1151.     
  1152.     (void) lseek(inf, offset, 0);
  1153. #endif    /*  !COFF  */
  1154.  
  1155. #ifdef    COFF
  1156.     nreloc = tsect.s_nreloc;
  1157. #else    /*  !COFF  */
  1158.     if  (read(inf, (char *)&filhdr, sizeof(filhdr)) != sizeof(filhdr))
  1159.         return;
  1160.     if  (filhdr.rtsize <= 0  &&  filhdr.rdsize <= 0)
  1161.         return;
  1162. #endif    /*  !COFF  */
  1163.  
  1164. #ifdef    COFF
  1165.     ldrseek(ldptr,1);
  1166.      while  (nreloc-- > 0)  {
  1167.         if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  1168. #else    /*  !COFF  */
  1169.     size  =  filhdr.rtsize;
  1170.  
  1171.     (void) lseek(inf, RTEXTPOS + offset, 0);
  1172.     for  (;  size >= sizeof(struct reloc);  size -= sizeof(crel))  {
  1173.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  1174. #endif    /*  !COFF  */
  1175.             lclash("rd trel");
  1176.  
  1177. #ifdef    COFF
  1178.          pos = crel.r_vaddr;
  1179.          mpos = crel.r_vaddr + trelpos;
  1180. #else    /*  !COFF  */
  1181.         pos = crel.rpos + outf->ef_tbase;
  1182.         mpos = crel.rpos + trelpos;
  1183. #endif    /*  !COFF  */
  1184.         gette(&mainfile, mpos, &mtstr);
  1185. #ifdef    COFF
  1186.         if (crel.r_type == R_ABS)
  1187.             rtype = R_NONE;
  1188.         else
  1189.             rtype = R_LONG;    /* what about PC-relative? */
  1190.         ldtbread(ldptr2,crel.r_symndx,&isym);
  1191.          lval = gettw(outf, pos, (int)rtype);
  1192.          mval = gettw(&mainfile, mpos, (int)rtype);
  1193. #else    /*  !COFF  */
  1194.         lval = gettw(outf, pos, (int)crel.rsize+1);
  1195.         mval = gettw(&mainfile, mpos, (int)crel.rsize+1);
  1196. #endif    /*  !COFF  */
  1197.         
  1198. #ifdef    COFF
  1199.         if ( isym.n_sclass != C_EXT ) {
  1200.         switch (convtosun(&isym)) {
  1201.          case  S_TEXT:
  1202. #else    /*  !COFF  */
  1203.         switch  (crel.rsegment)  {
  1204.         case  RTEXT:
  1205. #endif    /*  !COFF  */
  1206.             if  (lval + trelpos - outf->ef_tbase != mval)
  1207.                 lclash("Trel");
  1208.             continue;
  1209. #ifdef    COFF
  1210.          case  S_DATA:
  1211. #else    /*  !COFF  */
  1212.         case  RDATA:
  1213. #endif    /*  !COFF  */
  1214.             if  (donedrel)  {
  1215.                 if  (lval + drelpos - outf->ef_dbase != mval)
  1216.                     lclash("Drel");
  1217.             }
  1218.             else  {
  1219.                 donedrel++;
  1220.                 drelpos = mval - lval + outf->ef_dbase;
  1221.             }
  1222.             continue;
  1223. #ifdef    COFF
  1224.          case  S_BSS:
  1225. #else    /*  !COFF  */
  1226.         case  RBSS:
  1227. #endif    /*  !COFF  */
  1228.             if  (donebrel)  {
  1229.                 if  (lval + brelpos - outf->ef_bbase != mval)
  1230.                     lclash("brel");
  1231.             }
  1232.             else  {
  1233.                 donebrel++;
  1234.                 brelpos = mval - lval + outf->ef_bbase;
  1235.             }
  1236.             continue;
  1237. #ifdef    COFF
  1238.                }
  1239.            } else {
  1240.              if  (crel.r_symndx >= outf->ef_stcnt)
  1241. #else    /*  !COFF  */
  1242.         case  REXT:
  1243.             if  (crel.rsymbol >= outf->ef_stcnt)
  1244. #endif    /*  !COFF  */
  1245.                 lclash("Bad sy no");
  1246. #ifdef    COFF
  1247.              csymb = outf->ef_stvec[symord[crel.r_symndx]];
  1248. #else    /*  !COFF  */
  1249.             csymb = outf->ef_stvec[crel.rsymbol];
  1250. #endif    /*  !COFF  */
  1251.             if  (csymb == NULL)
  1252.                 continue;
  1253.             switch  (csymb->s_type)  {
  1254. #ifdef    COFF
  1255.             case  S_UNDF:
  1256. #else    /*  !COFF  */
  1257.             case  N_UNDF:
  1258. #endif    /*  !COFF  */
  1259.                 reassign(csymb, mval - lval);
  1260.                 break;
  1261. #ifdef    COFF
  1262.             case  S_ABS:
  1263. #else    /*  !COFF  */
  1264.             case  N_ABS:
  1265. #endif    /*  !COFF  */
  1266.                 if  (lval + csymb->s_value != mval)
  1267.                     lclash("abs rel");
  1268.                 break;
  1269. #ifdef    COFF
  1270.             case  S_TEXT:
  1271. #else    /*  !COFF  */
  1272.             case  N_TEXT:
  1273. #endif    /*  !COFF  */
  1274.                 if  (lval + csymb->s_value != mval)
  1275.                     lclash("text rel");
  1276.                 break;
  1277. #ifdef    COFF
  1278.             case  S_DATA:
  1279. #else    /*  !COFF  */
  1280.             case  N_DATA:
  1281. #endif    /*  !COFF  */
  1282.                 if  (lval + csymb->s_value != mval)
  1283.                     lclash("data rel");
  1284.                 break;
  1285. #ifdef    COFF
  1286.             case  S_BSS:
  1287. #else    /*  !COFF  */
  1288.             case  N_BSS:
  1289. #endif    /*  !COFF  */
  1290.                 if  (lval + csymb->s_value != mval)
  1291.                     lclash("bss rel");
  1292.                 break;
  1293. #ifdef    COFF
  1294.              case  S_COMM:
  1295. #else    /*  !COFF  */
  1296.             case  COMM:
  1297. #endif    /*  !COFF  */
  1298.                 reassign(csymb, mval - lval);
  1299.                 break;
  1300.             }
  1301.             mtstr.t_relsymb = csymb;
  1302.             mtstr.t_reldisp = lval;
  1303. #ifndef    COFF
  1304.             break;
  1305. #endif    /*  !COFF  */
  1306.         }
  1307.     }
  1308.     
  1309.     /*
  1310.      *    Relocate data and bss if possible.
  1311.      */
  1312.     
  1313.     if  (donebrel)  {
  1314. #ifdef    COFF
  1315.         zapdat(S_BSS, brelpos);
  1316. #else    /*  !COFF  */
  1317.         zapdat(N_BSS, brelpos);
  1318. #endif    /*  !COFF  */
  1319.         dhere++;
  1320.     }
  1321.     
  1322.     if  (!donedrel)
  1323.         return;
  1324.         
  1325.  
  1326. #ifdef    COFF
  1327.     zapdat(S_DATA, drelpos);
  1328. #else    /*  !COFF  */
  1329.     zapdat(N_DATA, drelpos);
  1330. #endif    /*  !COFF  */
  1331.     
  1332.     /*
  1333.      *    And now repeat all that for data relocations if possible
  1334.      */
  1335.     
  1336. #ifdef    COFF
  1337.     nreloc = tsect.s_nreloc;
  1338.  
  1339.     ldrseek(ldptr,2);
  1340. #else    /*  !COFF  */
  1341.     size  =  filhdr.rdsize;
  1342. #endif    /*  !COFF  */
  1343.     
  1344. #ifdef    COFF
  1345.     while (nreloc-- > 0) {
  1346.         if  (FREAD((char *)&crel, sizeof(crel),1,ldptr) != 1)
  1347. #else    /*  !COFF  */
  1348.     (void) lseek(inf, RDATAPOS + offset, 0);
  1349.     for  (;  size >= sizeof(struct reloc); size -= sizeof(crel))  {
  1350.         if  (read(inf, (char *)&crel, sizeof(crel)) != sizeof(crel))
  1351. #endif    /*  !COFF  */
  1352.             lclash("Rd drel");
  1353.  
  1354. #ifdef    COFF
  1355.          if  (crel.r_type == R_ABS)
  1356. #else    /*  !COFF  */
  1357.         if  (crel.rsize != RLONG)
  1358. #endif    /*  !COFF  */
  1359.             continue;
  1360.  
  1361. #ifdef    COFF
  1362.          pos = crel.r_vaddr;
  1363.          mpos = crel.r_vaddr + drelpos;
  1364. #else    /*  !COFF  */
  1365.         pos = crel.rpos + outf->ef_dbase;
  1366.         mpos = crel.rpos + drelpos;
  1367. #endif    /*  !COFF  */
  1368.         getde(&mainfile, mpos, &mdstr);
  1369. #ifdef    COFF
  1370.         rtype = R_LONG;        /* what about PC-relative? */
  1371.         ldtbread(ldptr2,crel.r_symndx,&isym);
  1372.  
  1373.          lval = getdw(outf, pos, (int)rtype);
  1374.          mval = getdw(&mainfile, mpos, (int)rtype);
  1375.         if ( isym.n_sclass != C_EXT ) {
  1376.         switch (convtosun(&isym)) {
  1377.          case  S_TEXT:
  1378. #else    /*  !COFF  */
  1379.         lval = getdw(outf, pos, (int)crel.rsize+1);
  1380.         mval = getdw(&mainfile, mpos, (int)crel.rsize+1);
  1381.         switch  (crel.rsegment)  {
  1382.         case  RTEXT:
  1383. #endif    /*  !COFF  */
  1384.             if  (lval + trelpos - outf->ef_tbase != mval)
  1385.                 lclash("Trel-d");
  1386.             continue;
  1387. #ifdef    COFF
  1388.          case  S_DATA:
  1389. #else    /*  !COFF  */
  1390.         case  RDATA:
  1391. #endif    /*  !COFF  */
  1392.             if  (lval + drelpos - outf->ef_dbase != mval)
  1393.                 lclash("Drel-d");
  1394.             continue;
  1395. #ifdef    COFF
  1396.          case  S_BSS:
  1397. #else    /*  !COFF  */
  1398.         case  RBSS:
  1399. #endif    /*  !COFF  */
  1400.             if  (donebrel)  {
  1401.                 if  (lval + brelpos - outf->ef_bbase != mval)
  1402.                     lclash("brel");
  1403.             }
  1404.             else  {
  1405.                 donebrel++;
  1406.                 brelpos = mval - lval + outf->ef_bbase;
  1407.             }
  1408.             continue;
  1409. #ifdef    COFF
  1410.                }
  1411.            } else { 
  1412.              if  (crel.r_symndx >= outf->ef_stcnt)
  1413. #else    /*  !COFF  */
  1414.         case  REXT:
  1415.             if  (crel.rsymbol >= outf->ef_stcnt)
  1416. #endif    /*  !COFF  */
  1417.                 lclash("Bad sy no");
  1418. #ifdef    COFF
  1419.              csymb = outf->ef_stvec[symord[crel.r_symndx]];
  1420. #else    /*  !COFF  */
  1421.             csymb = outf->ef_stvec[crel.rsymbol];
  1422. #endif    /*  !COFF  */
  1423.             if  (csymb == NULL)
  1424.                 continue;
  1425.             switch  (csymb->s_type)  {
  1426. #ifdef    COFF
  1427.             case  S_UNDF:
  1428. #else    /*  !COFF  */
  1429.             case  N_UNDF:
  1430. #endif    /*  !COFF  */
  1431.                 reassign(csymb, mval - lval);
  1432.                 break;
  1433. #ifdef    COFF
  1434.             case  S_ABS:
  1435. #else    /*  !COFF  */
  1436.             case  N_ABS:
  1437. #endif    /*  !COFF  */
  1438.                 if  (lval + csymb->s_value != mval)
  1439.                     lclash("abs rel");
  1440.                 break;
  1441. #ifdef    COFF
  1442.             case  S_TEXT:
  1443. #else    /*  !COFF  */
  1444.             case  N_TEXT:
  1445. #endif    /*  !COFF  */
  1446.                 if  (lval + csymb->s_value != mval)
  1447.                     lclash("text rel");
  1448.                 break;
  1449. #ifdef    COFF
  1450.             case  S_DATA:
  1451. #else    /*  !COFF  */
  1452.             case  N_DATA:
  1453. #endif    /*  !COFF  */
  1454.                 if  (lval + csymb->s_value != mval)
  1455.                     lclash("data rel");
  1456.                 break;
  1457. #ifdef    COFF
  1458.             case  S_BSS:
  1459. #else    /*  !COFF  */
  1460.             case  N_BSS:
  1461. #endif    /*  !COFF  */
  1462.                 if  (lval + csymb->s_value != mval)
  1463.                     lclash("bss rel");
  1464.                 break;
  1465. #ifdef    COFF
  1466.              case  S_COMM:
  1467. #else    /*  !COFF  */
  1468.             case  COMM:
  1469. #endif    /*  !COFF  */
  1470.                 reassign(csymb, mval - lval);
  1471.                 break;
  1472.             }
  1473.             mtstr.t_relsymb = csymb;
  1474.             mtstr.t_reldisp = lval;
  1475. #ifndef    COFF
  1476.             break;
  1477. #endif    /*  !COFF  */
  1478.         }
  1479.     }
  1480.  
  1481.     if  (dhere || !donebrel)
  1482.         return;
  1483.  
  1484. #ifdef    COFF
  1485.     zapdat(S_BSS, brelpos);
  1486. #else    /*  !COFF  */
  1487.     zapdat(N_BSS, brelpos);
  1488. #endif    /*  !COFF  */
  1489. }
  1490.